package com.qingzhuge.scheduler.autoconfigure;

import com.qingzhuge.context.SpringContext;
import com.qingzhuge.autoconfigure.QingTingProperties;
import com.qingzhuge.scheduler.annotation.TaskEntity;
import com.qingzhuge.scheduler.annotation.TaskEntityMethod;
import com.qingzhuge.scheduler.entity.SysTaskJob;
import com.qingzhuge.scheduler.entity.SysTaskScheduled;
import com.qingzhuge.scheduler.service.ISysTaskJobService;
import com.qingzhuge.scheduler.service.ISysTaskScheduledService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import java.lang.annotation.Annotation;
import java.util.List;

/**
 * @author : zero.xiao
 * @description : 扫描系统中存在的任务对象
 * @date :2019-05-17 18:01
 * @modified :
 */
@Slf4j
@Order
@Component
public class SysTaskJobRunner  implements ApplicationRunner {
    @Resource
    private ISysTaskJobService taskJobService;

    @Resource
    private ISysTaskScheduledService scheduledService;

    @Resource
    private QingTingProperties properties;

    @Override
    public void run(ApplicationArguments args) {
        if(properties.isInitData() || taskJobService.count() < 1) {
            log.debug("初始化任务计划信息...");
            //扫描所有的 spring Service
            String[] beanNames = SpringContext.getBeanNamesForAnnotation(Service.class);
            forBeans(beanNames);
            beanNames = SpringContext.getBeanNamesForAnnotation(Component.class);
            forBeans(beanNames);
        }
        //启动系统任务
        this.runTaskJob();
    }

    private void forBeans(String[] beanNames) {
        if (null != beanNames) {
            for (String beanName : beanNames) {
                TaskEntity annotation = SpringContext.findAnnotationOnBean(beanName, TaskEntity.class);
                if (annotation == null) {
                    continue;
                }
                Class<?> taskCls = SpringContext.getType(beanName);
                log.debug("有任务计划：{}", taskCls);
                ReflectionUtils.doWithMethods(taskCls, method -> {
                    Annotation[] annotations = AnnotationUtils.getAnnotations(method);
                    if (null != annotations) {
                        for (Annotation an : annotations) {
                            if (an instanceof TaskEntityMethod) {
                                SysTaskJob taskJob = SysTaskJob.of(beanName, method.getName());
                                taskJob.setName(annotation.name());
                                taskJob.setMethodName(((TaskEntityMethod) an).name());
                                log.debug("有任务计划：{}", taskJob);
                                saveTaskJob(taskJob);
                            }
                        }
                    }
                });
            }
        }
    }

    private void saveTaskJob(SysTaskJob taskJob){
        if (null != taskJob) {
            taskJobService.save(taskJob);
        }
    }

    /**启动系统中的所有任务*/
    private void runTaskJob(){
        List<SysTaskScheduled> scheduleds = scheduledService.findAll();
        if (null != scheduleds && scheduleds.size() > 0) {
            scheduleds.forEach(s->{
                if (null != s.getStatus() && s.getStatus() == 1) {
                    scheduledService.task(s);
                }
            });
        }
    }
}
